﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using PMServiceDesk.DataAccess;
using PMServiceDesk.DataType;
using PMServiceDesk.Parameters.Constantes;
using PMServiceDesk.Utils.ManejoDatos;

namespace PMServiceDesk.BusinessLogic
{
    public class LineaBaseImportarLogic
    {
        public List<LineaBaseImportarType> Importar(string proyectoId,string path)
        {
            List<LineaBaseImportarType> importacion = new LineaBaseImportarData().CargarLista(path);

            List<TipoPaqueteTrabajoType> tiposPaqueteTrabajo = new TipoPaqueteTrabajoLogic().CargarPorProyecto(proyectoId, "1");

            List<EstadoPaqueteTrabajoType> estadosPaqueteTrabajo = new EstadoPaqueteTrabajoLogic().CargarEstadosInicialesPorProyecto(proyectoId);

            List<RecursoType> recursos = new RecursoLogic().CargarRecursosVigentesPorProyecto(proyectoId);

            List<UsuarioRecursoType> usuarios = new UsuarioRecursoLogic().CargarUsuariosPorProyecto(proyectoId);

            //Actualizo el registro de los paquetes de trabajo
            foreach(LineaBaseImportarType l in importacion)
            {
                //Si es paquete de trabajo continuo
                if(!this._setTipoPaqueteTrabajo(l,tiposPaqueteTrabajo,estadosPaqueteTrabajo)) continue;

                //Recurso Responsable
                if (!this._setResponsablePaqueteTrabajo(l, recursos, usuarios)) continue;

                l.RecursosImportar = this._setRecursosPaqueteTrabajo(l,recursos,usuarios);
            }

            return this._actualizarFechasEntregablesPorJerarquia(importacion);
        }

        private bool _setTipoPaqueteTrabajo(LineaBaseImportarType lineaBase, List<TipoPaqueteTrabajoType> tiposPaqueteTrabajo, List<EstadoPaqueteTrabajoType> estadosPaqueteTrabajo)
        {
            if (lineaBase.Tipo == "") return false;

            var arr = (
                        from registro in tiposPaqueteTrabajo
                        where registro.Nombre.ToUpper() == lineaBase.Tipo.ToUpper()
                        select registro
                      ).ToList();

            if (!arr.Any()) return false;

            lineaBase.EsPaqueteTrabajo = true;
            lineaBase.TipoPaqueteTrabajoId = arr.First().Id;
            lineaBase.EstadoPaqueteTrabajoId = (
                                                from registro in estadosPaqueteTrabajo
                                                where registro.TipoPaqueteTrabajoId == lineaBase.TipoPaqueteTrabajoId
                                                select registro
                                                ).First().Id;

            return true;
        }

        private bool _setResponsablePaqueteTrabajo(LineaBaseImportarType lineaBase, List<RecursoType> recursos, List<UsuarioRecursoType> usuarios)
        {
            var recursosAux = (
                                from registro in recursos
                                where registro.TipoRecursoId == Parametros.TipoRecurso_Humano
                                && registro.Abreviatura.ToUpper() == lineaBase.Responsable.ToUpper()
                                select registro
                              ).ToList();

            if (!recursosAux.Any()) return false;

            lineaBase.RecursoResponsableId = recursosAux.First().Id;

            var usuariosAux = (
                                from registro in usuarios
                                where registro.RecursoId == lineaBase.RecursoResponsableId
                                select registro
                               ).ToList();

            if (!usuariosAux.Any()) return false;
    
            lineaBase.UsuarioResponsableId = usuariosAux.First().Id;

            return true;
        }

        private List<RecursoImportarType> _setRecursosPaqueteTrabajo(LineaBaseImportarType lineaBase, List<RecursoType> recursos, List<UsuarioRecursoType> usuarios)
        {
            List<RecursoImportarType> recursosImportar = new List<RecursoImportarType>();
            RecursoImportarType recursoImportar = null;
            string cantidades = null;
            string[] cantidadesAux = null;

            //Recursos del paquete de trabajo
            foreach (string recurso in lineaBase.RecursosFormat.Split(','))
            {
                recursoImportar = new RecursoImportarType();

                recursoImportar.CodigoAbreviatura = recurso.Split('[')[0].Trim().ToUpper();

                if (recursoImportar.CodigoAbreviatura == "") continue;

                //Si es del tipo costo fijo no tiene ingresado ninguna cantidad
                if (recurso.Split('[').Length == 1)
                    cantidades = "";
                else
                    cantidades = recurso.Split('[')[1].Trim().Replace("]", "").Trim();

                cantidadesAux = cantidades.Split('-');

                if (cantidadesAux.Length == 1)
                {
                    cantidades = cantidadesAux[0].Trim();

                    if (cantidades == "")//Recurso Costo Fijo
                    {
                        recursoImportar.TipoRecursoId = Parametros.TipoRecurso_CostoFijo;
                        recursoImportar.Porcentaje = 100;
                        recursoImportar.Cantidad = 1;
                    }
                    else if (cantidades.IndexOf("%") >= 0) //Recurso Humano
                    {
                        recursoImportar.TipoRecursoId = Parametros.TipoRecurso_Humano;
                        recursoImportar.Porcentaje = ConvertFormat.Char_To_Decimal(cantidades.Replace("%", "").Trim());
                        recursoImportar.Cantidad = 1;
                    }
                    else //Material
                    {
                        recursoImportar.TipoRecursoId = Parametros.TipoRecurso_Material;
                        recursoImportar.Porcentaje = 100;
                        recursoImportar.Cantidad = Convert.ToInt32(cantidades);
                    }
                }
                else //Recurso Por Hora
                {
                    recursoImportar.TipoRecursoId = Parametros.TipoRecurso_PorHora;
                    recursoImportar.Porcentaje = ConvertFormat.Char_To_Decimal(cantidadesAux[1].Trim().Replace("%", "").Trim());
                    recursoImportar.Cantidad = Convert.ToInt32(cantidadesAux[0].Trim());
                }

                var recursosAux = (
                                    from registro in recursos
                                    where registro.TipoRecursoId == recursoImportar.TipoRecursoId
                                    && registro.Abreviatura.ToUpper() == recursoImportar.CodigoAbreviatura
                                    select registro
                                   ).ToList();

                if (!recursosAux.Any()) continue;

                recursoImportar.RecursoId = recursosAux.First().Id;

                if (recursoImportar.TipoRecursoId == Parametros.TipoRecurso_Humano)
                {
                    var usuariosAux = (
                                        from registro in usuarios
                                        where registro.RecursoId == recursoImportar.RecursoId
                                        select registro
                                      ).ToList();

                    if (usuariosAux.Any()) recursoImportar.UsuarioId = usuariosAux.First().Id;
                }

                recursosImportar.Add(recursoImportar);
            }

            return recursosImportar;
        }

        private List<LineaBaseImportarType> _actualizarFechasEntregablesPorJerarquia(List<LineaBaseImportarType> importacion)
        {
            //Actualizo las fecha de inicio y fin de las tareas que no son paquetes de trabajo por jerarquias
            foreach (LineaBaseImportarType l in importacion)
            {
                if (l.EsPaqueteTrabajo) continue;

                l.FechaInicio = (
                                    from registro in importacion
                                    orderby ConvertFormat.Char_To_Date(registro.FechaInicio) ascending
                                    where registro.EsPaqueteTrabajo == true
                                    && registro.CodigoCuenta.Substring(0, l.CodigoCuenta.Length) == l.CodigoCuenta
                                    select registro
                                 ).First().FechaInicio;

                l.FechaFin = (
                                    from registro in importacion
                                    orderby ConvertFormat.Char_To_Date(registro.FechaFin) descending
                                    where registro.EsPaqueteTrabajo == true
                                    && registro.CodigoCuenta.Substring(0, l.CodigoCuenta.Length) == l.CodigoCuenta
                                    select registro
                                 ).First().FechaFin;
            }

            return importacion;
        }

    }
}
